Skip to content

Apply various formatting fixes - #80

Merged
nene merged 5 commits into
nene:masterfrom
joelmukuthu:fix/formatting-fixes
Sep 7, 2026
Merged

nene merged 5 commits into
nene:masterfrom
joelmukuthu:fix/formatting-fixes

Conversation

@joelmukuthu

@joelmukuthu joelmukuthu commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Fixes:

Comment thread src/syntax/expr.ts Outdated
@joelmukuthu
joelmukuthu force-pushed the fix/formatting-fixes branch 3 times, most recently from d26d012 to 120b664 Compare August 11, 2026 06:45

@nene nene left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the pull request. I've been busy with other stuff. Finally got to reviewing this.

In general it looks good:

  • Break long WHEN/THEN clauses into separate lines
    • Needs some more thought on how to actually indent these.
  • Break long COMMENT ON clauses into separate lines
    • Doesn't really match with the indentation suggested in #76
  • Break long CREATE INDEX clauses into separate lines ✅
  • Break long binary expressions into separate lines ✅
  • Avoid line-break between empty parenthesis
    • This is the trickiest change. The general logic looks sound. I do have some recommendations though.

Comment thread test/expr/expr.test.ts Outdated
Comment on lines +212 to +218
SELECT
CASE
WHEN column_name = 1
THEN result_name
WHEN column_name = 2
THEN other_result
ELSE foo

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this not so easy to read, because WHEN and THEN blocks are indented the same amount. IMHO it's sort of like formatting if-else in some other language like so:

if x > 10
return 15
else if x < 10
return 20

It also doesn't match with how the procedural version of CASE expression gets formatted:

CASE
  WHEN column_name = 1 THEN
    SELECT \good'
  WHEN columne_name = 2 THEN
    SELECT 'bad'
  ELSE
    SELECT 'other'
END CASE

See case.test.ts

I would go with similar indentation for the long WHEN..THEN blocks in general:

CASE
  WHEN column_name = 1 THEN
    result_name
  WHEN columne_name = 2 THEN
    other_result
  ELSE
    foo
END CASE

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. So for multi-line WHEN/THEN clauses, will it be okay to format as follows?

CASE
  WHEN 
    column_name = 1 
    AND (column_name = 2 OR column_name = 3)
    AND column_name = 4 THEN
      result_name
      AND (result_name OR result_name)
  WHEN columne_name = 5 THEN
    other_result
  ELSE
    foo
END

@nene nene Aug 31, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to treat the WHEN .. THEN pair as ( .. ) pair in C-style if statement, which in Prettier would get formatted like:

if (
  column_name === 1 
  && (column_name === 2 OR column_name === 3)
  && column_name === 4
) {
  return result_name
} else if (columne_name === 5) {
  return other_result;
}

So in SQL this would be:

CASE
  WHEN 
    column_name = 1 
    AND (column_name = 2 OR column_name = 3)
    AND column_name = 4
  THEN
    result_name
  WHEN columne_name = 5 THEN
    other_result
  ELSE
    foo
END

This has the nice property, that the body of THEN is always indented the same amount. When the code between WHEN..THEN needs to wrap to multiple lines, the code coming after THEN won't need to be reformatted in any way.

Comment thread test/postgresql/comment.test.ts
Comment thread src/syntax/expr.ts Outdated
Comment thread src/syntax/expr.ts Outdated
@joelmukuthu

Copy link
Copy Markdown
Contributor Author

Thanks for the review. Everything you write makes sense! I'm going to be AFK for the next 2 weeks so I'll respond/make updates after :)

@joelmukuthu

Copy link
Copy Markdown
Contributor Author

@nene this is ready for re-review :)

Comment thread test/expr/expr.test.ts
Comment on lines +183 to +211
it(`breaks long WHEN/THEN into separate lines`, async () => {
await test(
dedent`
SELECT
CASE
WHEN column_name = 1 THEN
result_name
END
`,
{ printWidth: 40 },
);
});

it(`breaks multiple long WHEN/THEN clauses without blank lines between them`, async () => {
await test(
dedent`
SELECT
CASE
WHEN column_name = 1 THEN
result_name
WHEN column_name = 2 THEN
other_result
ELSE
foo
END
`,
{ printWidth: 40 },
);
});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these tests have become obsolete now that we always break. Best to remove

@nene nene left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes.

The CASE formatting is still problematic. Need to take another stab at this. Everything besides this is good.

Comment thread test/expr/expr.test.ts
Comment on lines 165 to 172
await test(dedent`
SELECT
CASE x
WHEN 1 THEN 'A'
ELSE 'B'
WHEN 1 THEN
'A'
ELSE
'B'
END

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I gave you the wrong idea when I said we should format the case expression the same as the case statement in procedural SQL. What I meant was, that we should format them similarly when they are so long that they don't fit on a single line. That is, I'd still expect to format the above as:

CASE x
  WHEN 1 THEN 'A'
  ELSE 'B'
END

Only when the expression doesn't fit on a single line should be break the WHEN..THEN or ELSE block to multiple lines like so:

CASE x
  WHEN 1 THEN
    'Something long in here'
  ELSE
    'Another long thing in here'
END

or when the condition part is long:

CASE x
  WHEN some_long_expression_in_here THEN
    'A'
  ELSE
    'B'
END

or extra long:

CASE x
  WHEN
    some_extra_long_expression_in_here
  THEN
    'A'
  ELSE
    'B'
END

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant was, that we should format them similarly when they are so long that they don't fit on a single line.

This was what I understood at first, but I changed the implementation because of the desired ELSE formatting. With the current code setup, the ELSE clause is formatted separately/independently, so a "short" ELSE gets formatted as follows (regardless of THENs formatting):

CASE x
  WHEN some_long_expression_in_here THEN
    'A'
  ELSE 'B'
END

Alternatively, the current implementation could be changed to couple WHEN/THEN/ELSE formatting, so we can know to break the ELSE statement if the WHEN/THEN statements also break.

Or alternatively, always break the statements, which also happens to look like if..else statements (with braces). So when I got to this point I thought this what you meant all along :)

Anyway to summarise, I think the options are:

  1. Format WHEN/THEN and ELSE independently and acknowledge that sometimes the ELSE will be formatted differently from the WHEN/THEN statements
  2. Update the formatting code to couple WHEN/THEN/ELSE formatting. I didn't explore this too much but I felt like it would be a non-trivial overhaul -- I could be wrong
  3. Always break THEN and ELSE clauses to the next line
  4. Maybe something else?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm leaning towards option 2. But I also don't really know how to easily achieve that. Although I'm not 100% sure we want that. The bad thing with this variant is that making one WHEN-block longer would cause a large reindent for all of them. That might or might not be what one desires. Like, if one has a long CASE expression with lots of small WHEN-THEN blocks, and then one that's a bit longer, it could be annoying to have everything split to multiple lines because of that one block. On the other hand, it can be annoying to have a mix of one-line and two-line WHEN-THEN blocks.

But option 1 is definitely the next best thing. And maybe it's even the better variant out of the two. Let's go with that and not try to fight too much with the general indentation approach of Prettier.

@nene

nene commented Sep 7, 2026

Copy link
Copy Markdown
Owner

I have to also point out that doing force-pushes to pull requests makes it hard for me to review the changes you have made. I find it already problematic when one simply rebases his commits on top of changed master branch, because even though the diff hasn't changed, Git just sees bunch of brand new commits with different hashes.

But it's especially bad when you change the commits themselves. I will have no idea what has changed since the last time I reviewed this. Currently I had to manually diff this from the command line against the old version of your PR to understand what you had changed in the mean time.

It really is the same as going back in time and changing history. It just creates a massive confusion. Or worse... it can end in unsolvable paradoxes :D

nene added a commit that referenced this pull request Sep 7, 2026
@nene
nene merged commit 868b3f9 into nene:master Sep 7, 2026
1 check passed
@nene

nene commented Sep 7, 2026

Copy link
Copy Markdown
Owner

I reverted the CASE-part of this PR and merged this in, as everything besides this was fine.

You can do a new PR for the CASE statement formatting.

@joelmukuthu

Copy link
Copy Markdown
Contributor Author

Thanks for the review and merge!

I need a little direction before opening a new PR for CASE formatting (see #80 (comment)). I elected to continue the discussion here but can switch back to the issue if needed.

And regarding rebasing/force-pushes, I absolutely understand. I'll stick to appending commits going forward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants